
// `include "/home/zzy/ysyx/oscpu/projects/rv64i/vsrc/Definitons.sv"
`include "Definitons.sv"
`timescale 1ns / 1ps
module SimTop(
    input                               clock                      ,
    input                               reset                      ,

    input              [  63:0]         io_logCtrl_log_begin       ,
    input              [  63:0]         io_logCtrl_log_end         ,
    input              [  63:0]         io_logCtrl_log_level       ,
    input                               io_perfInfo_clean          ,
    input                               io_perfInfo_dump           ,

    output                              io_uart_out_valid          ,
    output             [   7:0]         io_uart_out_ch             ,
    output                              io_uart_in_valid           ,
    input              [   7:0]         io_uart_in_ch               
);

// if_stage
wire                   [  63:0]         pc                         ;
wire                   [  31:0]         inst                       ;

wire                                    IM_valid                   ;
wire                                    IM_ready                   ;
wire                   [  63:0]         IM_addr                    ;
wire                   [  31:0]         IM_rdata                   ;
wire                   [  63:0]         ram_addr                   ;
wire                   [  63:0]         DM_wdata                   ;
wire                   [   7:0]         DM_wstrb                   ;
wire                   [  63:0]         DM_rdata                   ;
wire                                    DM_valid                   ;
wire                                    DM_ready                   ;
wire                   [  63:0]         DM_addr                    ;
wire                   [  63:0]         mem_addr                    ;
wire                   [  63:0]         data_addr                  ;
wire                   [  63:0]         instr_addr                 ;
reg                    [  63:0]         pc_r                       ;
reg                    [  31:0]         inst_r                     ;
reg                                     inst_vld_r                ;
reg                                     cmt_wen_r                    ;
reg                    [   7:0]         cmt_wdest_r                  ;
reg                    [  63:0]         cmt_wdata_r                  ;
reg                                     skip_r                    ;
assign IM_ready = 1'b1;
assign IM_rdata = inst;
assign pc = IM_addr;
assign mem_addr = DM_addr[30:0];
  CORE_TOP top_inst
    (

    .clk                               (clock                     ),
    .rst_n                             (!reset                    ),
    // .IM_ready                          (IM_ready                  ),
    .IM_valid                          (IM_valid                  ),
    .IM_rdata                          (IM_rdata                  ),
    .IM_addr                           (IM_addr                   ),
    .DM_wdata                          (DM_wdata                  ),
    .DM_wstrb                          (DM_wstrb                  ),
    .DM_valid                          (DM_valid                  ),
    .DM_addr                           (DM_addr                   ),
    .DM_rdata                          (DM_rdata                  )
    // .trap                              (trap                      ) 
    );
RAM_1W2R RAM_INST(
    .clk                               (clock                     ),
    .inst_addr                         (pc                        ),
    .inst_ena                          (IM_valid                  ),
    .inst                              (inst                      ),
    .mem_wr_en                         (DM_valid                  ),
    .mem_rd_en                         (!DM_wstrb                 ),
    .byte_enble                        (DM_wstrb                  ),
    .mem_addr                          (mem_addr                   ),
    .mem_wr_data                       (DM_wdata                  ),
    .mem_rd_data                       (DM_rdata                  ) 
);
always @(posedge clock) begin
    skip_r <=  top_inst.csr_addr == 12'hb00 &&  top_inst.I_type.C;
    pc_r <= pc;
    inst_r <= inst;
    inst_vld_r <= inst_valid;
    cmt_wen_r <= top_inst.Wreg_en;
    cmt_wdest_r <= top_inst.xaddr.rd;
    cmt_wdata_r <= top_inst.rd;
end
// Difftest
reg                                     cmt_wen                    ;
reg                    [   7:0]         cmt_wdest                  ;
reg                    [  63:0]         cmt_wdata                  ;
reg                    [  63:0]         cmt_pc                     ;
reg                    [  31:0]         cmt_inst                   ;
reg                                     cmt_valid                  ;
reg                                     trap                       ;
reg                    [   7:0]         trap_code                  ;
reg                    [  63:0]         cycleCnt                   ;
reg                    [  63:0]         instrCnt                   ;
reg                                     cmt_skip                    ;
reg [63:0] regs_diff [0 : 31];
wire                                    inst_valid = IM_valid;//(pc != 64'h00000000_80000000) && 
integer                 i;
always @(negedge clock) begin
  if (reset) begin
    {cmt_wen, cmt_wdest, cmt_wdata, cmt_pc, cmt_inst, cmt_valid, trap, trap_code, cycleCnt, instrCnt} <= 0;
  end
  else if (~trap) begin
    // cmt_wen <= top_inst.Wreg_en;
    // cmt_wdest <= top_inst.xaddr.rd;
    // cmt_wdata <= top_inst.rd;
    cmt_wen <= cmt_wen_r;
    cmt_wdest <= cmt_wdest_r;
    cmt_wdata <= cmt_wdata_r;
    // cmt_pc <= pc;
    // cmt_inst <= inst;
    // cmt_valid <= inst_valid;
    cmt_pc <= pc_r;
    cmt_inst <= inst_r;
    cmt_valid <= inst_vld_r;
		// regs_diff <= ;

    trap <= inst[6:0] == 7'h6b;
    trap_code <= 0;
    cycleCnt <= cycleCnt + 1;
    instrCnt <= instrCnt + inst_vld_r;
    cmt_skip <= skip_r;
// instrCnt <= instrCnt + inst_valid;
    for(i =1; i<32;i=i+1)
        regs_diff[i] <= top_inst.x[i];
  end
end

DifftestInstrCommit DifftestInstrCommit(
    .clock                             (clock                     ),
    .coreid                            (0                         ),
    .index                             (0                         ),
    .valid                             (cmt_valid                 ),
    .pc                                (cmt_pc                    ),
    .instr                             (cmt_inst                  ),
    .skip                              (cmt_skip                  ),
    .isRVC                             (0                         ),
    .scFailed                          (0                         ),
    .wen                               (cmt_wen                   ),
    .wdest                             (cmt_wdest                 ),
    .wdata                             (cmt_wdata                 ) 
);

DifftestArchIntRegState DifftestArchIntRegState (
    .clock                             (clock                     ),
    .coreid                            (0                         ),
    .gpr_0                             (0                         ),
    .gpr_1                             (regs_diff[1]              ),
    .gpr_2                             (regs_diff[2]              ),
    .gpr_3                             (regs_diff[3]              ),
    .gpr_4                             (regs_diff[4]              ),
    .gpr_5                             (regs_diff[5]              ),
    .gpr_6                             (regs_diff[6]              ),
    .gpr_7                             (regs_diff[7]              ),
    .gpr_8                             (regs_diff[8]              ),
    .gpr_9                             (regs_diff[9]              ),
    .gpr_10                            (regs_diff[10]             ),
    .gpr_11                            (regs_diff[11]             ),
    .gpr_12                            (regs_diff[12]             ),
    .gpr_13                            (regs_diff[13]             ),
    .gpr_14                            (regs_diff[14]             ),
    .gpr_15                            (regs_diff[15]             ),
    .gpr_16                            (regs_diff[16]             ),
    .gpr_17                            (regs_diff[17]             ),
    .gpr_18                            (regs_diff[18]             ),
    .gpr_19                            (regs_diff[19]             ),
    .gpr_20                            (regs_diff[20]             ),
    .gpr_21                            (regs_diff[21]             ),
    .gpr_22                            (regs_diff[22]             ),
    .gpr_23                            (regs_diff[23]             ),
    .gpr_24                            (regs_diff[24]             ),
    .gpr_25                            (regs_diff[25]             ),
    .gpr_26                            (regs_diff[26]             ),
    .gpr_27                            (regs_diff[27]             ),
    .gpr_28                            (regs_diff[28]             ),
    .gpr_29                            (regs_diff[29]             ),
    .gpr_30                            (regs_diff[30]             ),
    .gpr_31                            (regs_diff[31]             ) 
);

DifftestTrapEvent DifftestTrapEvent(
    .clock                             (clock                     ),
    .coreid                            (0                         ),
    .valid                             (trap                      ),
    .code                              (trap_code                 ),
    .pc                                (cmt_pc                    ),
    .cycleCnt                          (cycleCnt                  ),
    .instrCnt                          (instrCnt                  ) 
);

DifftestCSRState DifftestCSRState(
    .clock                             (clock                     ),
    .coreid                            (0                         ),
    .priviledgeMode                    (0                         ),
    .mstatus                           (0                         ),
    .sstatus                           (0                         ),
    .mepc                              (0                         ),
    .sepc                              (0                         ),
    .mtval                             (0                         ),
    .stval                             (0                         ),
    .mtvec                             (0                         ),
    .stvec                             (0                         ),
    .mcause                            (0                         ),
    .scause                            (0                         ),
    .satp                              (0                         ),
    .mip                               (0                         ),
    .mie                               (0                         ),
    .mscratch                          (0                         ),
    .sscratch                          (0                         ),
    .mideleg                           (0                         ),
    .medeleg                           (0                         ) 
);

DifftestArchFpRegState DifftestArchFpRegState(
    .clock                             (clock                     ),
    .coreid                            (0                         ),
    .fpr_0                             (0                         ),
    .fpr_1                             (0                         ),
    .fpr_2                             (0                         ),
    .fpr_3                             (0                         ),
    .fpr_4                             (0                         ),
    .fpr_5                             (0                         ),
    .fpr_6                             (0                         ),
    .fpr_7                             (0                         ),
    .fpr_8                             (0                         ),
    .fpr_9                             (0                         ),
    .fpr_10                            (0                         ),
    .fpr_11                            (0                         ),
    .fpr_12                            (0                         ),
    .fpr_13                            (0                         ),
    .fpr_14                            (0                         ),
    .fpr_15                            (0                         ),
    .fpr_16                            (0                         ),
    .fpr_17                            (0                         ),
    .fpr_18                            (0                         ),
    .fpr_19                            (0                         ),
    .fpr_20                            (0                         ),
    .fpr_21                            (0                         ),
    .fpr_22                            (0                         ),
    .fpr_23                            (0                         ),
    .fpr_24                            (0                         ),
    .fpr_25                            (0                         ),
    .fpr_26                            (0                         ),
    .fpr_27                            (0                         ),
    .fpr_28                            (0                         ),
    .fpr_29                            (0                         ),
    .fpr_30                            (0                         ),
    .fpr_31                            (0                         ) 
);

endmodule

`include "Definitons.sv"
`timescale 1ns / 1ps
module RAM_1W2R(
    input                               clk                        ,
    
    input              [  63:0]         inst_addr                  ,
    input                               inst_ena                   ,
    output             [  31:0]         inst                       ,

    // DATA PORT
    input                               mem_wr_en                  ,
    input                               mem_rd_en                  ,
    input              [   7:0]         byte_enble                 ,
    input              [  63:0]         mem_addr                   ,
    input              [  63:0]         mem_wr_data                ,
    output reg         [  63:0]         mem_rd_data                 
);
    wire[  63:0] inst_2 = ram_read_helper(inst_ena,{3'b000,(inst_addr-64'h0000_0000_8000_0000)>>3});

    assign inst = inst_addr[2] ? inst_2[63:32] : inst_2[31:0];

    // DATA PORT 
    wire [  63:0] now_rd_data = ram_read_helper(mem_rd_en, mem_addr >> 3);
    
    assign mem_rd_data = now_rd_data;//mem_addr[2] ? {now_rd_data[63:0]} : {now_rd_data[31:0],now_rd_data[63:32]};

    // 掩码转换
    wire [  63:0] wmask = { {8{byte_enble[7]}},
                                {8{byte_enble[6]}},
                                {8{byte_enble[5]}},
                                {8{byte_enble[4]}},
                                {8{byte_enble[3]}},
                                {8{byte_enble[2]}},
                                {8{byte_enble[1]}},
                                {8{byte_enble[0]}}};

    wire [  63:0]wr_data = mem_wr_data;

    always @(posedge clk) begin
        ram_write_helper(mem_addr>>3, wr_data, wmask, mem_wr_en);
    end

endmodule
//     // INST PORT

//     wire[  63:0] inst_2 = ram_read_helper(inst_ena,{3'b000,(inst_addr-64'h00000000_80000000)>>3});

//     assign inst = inst_addr[2] ? inst_2[63:32] : inst_2[31:0];

//     // DATA PORT 
//     // wire [  63:0] now_rd_data = ram_read_helper(mem_rd_en, {3'b000,(mem_addr-64'h00000000_80000000)>>3});
//     wire [  63:0] now_rd_data = ram_read_helper(mem_rd_en, mem_addr-32'h80000000);
//     assign mem_rd_data = mem_addr[2] ? {now_rd_data[63:0]} : {now_rd_data[31:0],now_rd_data[63:32]};

//     // 掩码转换
//     wire [  63:0] wmask = { {8{byte_enble[7]}},
//                                 {8{byte_enble[6]}},
//                                 {8{byte_enble[5]}},
//                                 {8{byte_enble[4]}},
//                                 {8{byte_enble[3]}},
//                                 {8{byte_enble[2]}},
//                                 {8{byte_enble[1]}},
//                                 {8{byte_enble[0]}}};

//     wire [  63:0]wr_data = mem_wr_data;//{mem_wr_data[31:0],mem_rd_data[63:32]};

//     always @(posedge clk) begin
//         ram_write_helper(mem_addr-32'h80000000, wr_data, wmask, mem_wr_en);
//         // ram_write_helper((mem_addr-64'h00000000_80000000)>>3, wr_data, wmask, mem_wr_en);
//     end

// endmodule